package k8s

import (
	db "hulk-api/databases"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"fmt"

	"strings"
	"k8s.io/client-go/kubernetes/scheme"
)


type DeploymentDetail struct {
	Name string						`json:"name"`
	Namespace string				`json:"namespace"`
	Labels map[string]string		`json:"labels"`
	Selector map[string]string		`json:"selector"`
	Replicas int32					`json:"replicas"`
	Strategy string					`json:"strategy"`
	MinReadySeconds int32			`json:"minreadyseconds"`
	RollUpdateStrategy string		`json:"rollupdatestrategy"`
	Status string					`json:"status"`

	CreateDate string				`json:"createdate"`
}

type ReplicaSet struct {
	Name string						`json:"name"`
	Labels map[string]string		`json:"labels"`
	Containers string				`json:"containers"`
	CreateDate string				`json:"createdate"`
	Images []string					`json:"images"`

	Status bool						`json:"status"`   //简单判断rs是否部署完毕
}

type Hpa struct {
	Name string						`json:"name"`
	TargetCpuPercent string			`json:"targetcpupercent"`
	CurrentCpuPercent string		`json:"currentcpupercent"`
	MinReplicas		int32			`json:"minreplicas"`
	MaxReplicas		int32			`json:"maxreplicas"`
	CreateDate		string			`json:"createdate"`
}



func GetKubernetesDeploymentDetail(ns string,deploy string)(dpdetail DeploymentDetail,newReplicaSets []ReplicaSet,oldReplicaSets []ReplicaSet,hpas []Hpa ,evns []Event,err error)  {
	dp,_ := clientset.AppsV1().Deployments(ns).Get(deploy,metav1.GetOptions{})
	dpdetail = DeploymentDetail{
		Name:  dp.Name,
		Namespace: dp.Namespace,
		Labels: dp.Labels,
		Selector: dp.Spec.Selector.MatchLabels,
		Replicas: dp.Status.Replicas,
		Strategy: string(dp.Spec.Strategy.Type),
		MinReadySeconds: dp.Spec.MinReadySeconds,
		RollUpdateStrategy: fmt.Sprintf("最大激增数: %d, 最大无效数: %d",dp.Spec.Strategy.RollingUpdate.MaxSurge.IntVal,dp.Spec.Strategy.RollingUpdate.MaxUnavailable.IntVal),
		Status: fmt.Sprintf("%d 个可用, %d 个不可用",dp.Status.AvailableReplicas,dp.Status.UnavailableReplicas),
		CreateDate: dp.CreationTimestamp.Format("2006-01-02 15:04:05"),
	}


	var selector []string
	for rsLabelK,rsLabelV := range  dp.Spec.Selector.MatchLabels {
			selector = append(selector,fmt.Sprintf("%s=%s",rsLabelK,rsLabelV))
	}

	rs,_ := clientset.AppsV1().ReplicaSets(ns).List(metav1.ListOptions{
		LabelSelector: strings.Join(selector,","),
	})

	for _,r := range rs.Items {
		var images []string
		for _,c := range  r.Spec.Template.Spec.Containers {
			//fmt.Printf(c.Image)
			images = append(images,c.Image)
		}
		// 新旧副本集判断
		if r.Status.Replicas>0 {
			go func() {}()
			newReplicaSets = append(newReplicaSets,ReplicaSet{
			Name: r.Name,
			Labels: r.Labels,
			Containers: fmt.Sprintf("%d / %d",r.Status.ReadyReplicas,r.Status.Replicas),
			CreateDate: r.CreationTimestamp.Format("2006-01-02"),
			Images: images,
			Status: func()(bool) {
				if r.Status.ReadyReplicas < r.Status.Replicas {
					return false
				}
				return  true
			}(),
		})
		} else {
			oldReplicaSets = append(oldReplicaSets,ReplicaSet{
				Name: r.Name,
				Labels: r.Labels,
				Containers: fmt.Sprintf("%d / %d",r.Status.ReadyReplicas,r.Status.Replicas),
				CreateDate: r.CreationTimestamp.Format("2006-01-02"),
				Images: images,
			})
		}

	}



	hpa,_ := clientset.AutoscalingV1().HorizontalPodAutoscalers(ns).List(metav1.ListOptions{

	})

	for _,h := range hpa.Items {
		if h.Spec.ScaleTargetRef.Name == dp.Name {
			hpas = append(hpas,Hpa{
				Name: h.Name,
				TargetCpuPercent: fmt.Sprintf("%d",*h.Spec.TargetCPUUtilizationPercentage) + "%",
				CurrentCpuPercent: fmt.Sprintf("%d",h.Status.CurrentCPUUtilizationPercentage) + "%",
				MinReplicas: *h.Spec.MinReplicas,
				MaxReplicas: h.Spec.MaxReplicas,
				CreateDate: h.CreationTimestamp.Format("2006-01-02"),
			})
		}
	}

	//eventSelector , _ := metav1.LabelSelectorAsSelector(dp.Spec.Selector)


	events,_ := clientset.CoreV1().Events(ns).Search(scheme.Scheme, dp)   //get the method to fetch events

	for _,item := range events.Items {

		evns = append(evns,Event{
			//Name: item.Name,
			//Kind: item.InvolvedObject.Kind,
			//
			//
			//Type: item.Type,

			Message: item.Message,
			Source: item.Source.Component + " " + item.Source.Host,
			ChildObject: item.InvolvedObject.FieldPath,
			Reason: item.Reason,
			Num: item.Count,
			LastOccurTime: item.LastTimestamp.Format("2006-01-02 15:04:05"),
		})
	}
	return
}


type TemplatePath struct {
	Name string			`json:"name"`
	Path string 		`json:"path"`
}

func (t TemplatePath) GetPath() (  templates []TemplatePath, err error) {

	//sql := fmt.Sprintf(" select account,name,email,department,role,lastLoginTime from user")
	rows, err := db.SqlDB.Query("select name,path from template where ref='k8s'")
	defer rows.Close()
	for rows.Next() {
		var tt TemplatePath
		rows.Scan(&tt.Name,&tt.Path)
		templates = append(templates, tt)
	}
	if err = rows.Err(); err != nil {
		return
	}
	return

}



